/*
    $Header: /Windows/Shell/ShellExt.root/ShellExt/src/misc.cpp 2     08-07-24 0:20 Ken $
    $Log: /Windows/Shell/ShellExt.root/ShellExt/src/misc.cpp $
 * 
 * 2     08-07-24 0:20 Ken
 * add hook key (inject.dll setwindowshookex)
 * 
 * 1     08-01-05 0:08 Ken
*/


#include "StdAfx.h"

#include "Misc.h"

#include <shlwapi.h>
#include <shlobj.h>

#ifdef DEBUG

VOID TRACE_SYSERR()
{
    LPVOID pvMsgBuf = NULL;
    DWORD  dwLastErr = GetLastError();
    FormatMessage ( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                    NULL, dwLastErr,
                    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                    (LPTSTR) &pvMsgBuf, 0, NULL );

    ATLTRACE(_T("GetLastError %d\r\n%s"), dwLastErr,
                      pvMsgBuf ? pvMsgBuf : _T("(No description available)") );
    if ( NULL != pvMsgBuf )
    {
        LocalFree ( pvMsgBuf );
    }
}

#else
VOID TRACE_SYSERR(){}
#endif    //#if DEBUG

//
//4 the PathMakeUniqueName has no ascii version!
// ptstrUnicPath: OUT the unique file name
// ptszSrcFileName: IN the file name with want to make a unique name
//
BOOL MakeUniqueName( TCHAR* ptstrUnicPath, UINT cchMax, TCHAR* pszPlate, const TCHAR* pszDir)
{
    USES_CONVERSION;

    WCHAR* pwstrUnicPath;
#ifdef UNICODE
    pwstrUnicPath=ptstrUnicPath;
#else
    WCHAR    wszUnicFileName [MAX_PATH];
    pwstrUnicPath=wszUnicFileName;
#endif

    if(FALSE==PathMakeUniqueName(pwstrUnicPath, cchMax, NULL,T2CW(pszPlate), T2CW(pszDir)))
    {
        ATLTRACE(_T("PathMakeUniqueName faild! pszDir:%s"), pszDir);
        TRACE_SYSERR();
        return FALSE;
    }

#ifndef UNICODE
    _tcsncpy(ptstrUnicPath, W2CT(wszUnicFileName), cchMax);
#endif

    return TRUE;
}

BOOL MakeUniqueFileName( TCHAR* pstrUnicPath, UINT cchMax, const TCHAR* pszFileName, const TCHAR* pszDir)
{
    ATLASSERT((pszFileName!=NULL) && (pszDir!=NULL));

    TCHAR    szFileName [MAX_PATH];
    TCHAR    szFilePath [MAX_PATH];

    // Remove the path - this reduces "C:\xyz\foo\stuff.exe" to "stuff.exe"
    _tcscpy_s( szFileName, pszFileName );
    PathStripPath ( szFileName );

    // get path
    _tcscpy_s( szFilePath, pszFileName );
    PathRemoveFileSpec(szFilePath);

    if(!_tcscmp(szFilePath, pszDir))
    {//the drag and drop in the same dir
        TCHAR    szUnicObjName [MAX_PATH];
        _tcsncpy_s(szUnicObjName, szFileName, ARRAYOF(szUnicObjName));
        //make unique name.
        PathAddBackslash ( szFilePath );
        if(FALSE==MakeUniqueName(pstrUnicPath, cchMax, szUnicObjName, szFilePath))
        {
            return FALSE;
        }
    }
    else
    {//the drag and drop not in the same dir
        _sntprintf ( pstrUnicPath, cchMax,  _T("%s\\%s"), pszDir, szFileName );
    }

    return TRUE;

}
// pszPath should be a full path name. such as: "c:\tmp\tmp.tmp"
BOOL GetVlmFlg(const TCHAR* pszPath, DWORD* pdwFlg)
{
    TCHAR    szVolumeName[]=_T("X:\\");
    if( (szVolumeName[1]!=pszPath[1]) || (szVolumeName[2]!=pszPath[2]) )
    {
        return FALSE;
    }
    szVolumeName[0]=pszPath[0];
    return GetVolumeInformation( szVolumeName, NULL, 0, NULL, NULL, pdwFlg, NULL, 0);
}

//
// dialog to select a folder
BOOL GetOpenFolderName(LPSTR pszSelDir, DWORD dwBufLen, HWND hwndOwn, LPSTR pszTitle)
{
    BROWSEINFO      bi;
    LPITEMIDLIST    pidl;

    BOOL fRet=FALSE;

    ZeroMemory(&bi, sizeof(bi));
    bi.hwndOwner = hwndOwn;
    bi.lpszTitle = pszTitle;
    bi.ulFlags = BIF_RETURNONLYFSDIRS;

    // dialog to select a folder
    pidl = SHBrowseForFolder(&bi);
    if (pidl)
    {
        TCHAR szFld[MAX_PATH];
        if( (FALSE!=SHGetPathFromIDList(pidl, szFld)) && (_tcslen(szFld) < dwBufLen) )
        {
            _tcscpy(pszSelDir, szFld);
            fRet=TRUE;
        }
    }

    // free the pidl using the shell's task allocator.
    LPMALLOC pMalloc = NULL;
    if (SHGetMalloc(&pMalloc) == NOERROR)
    {
        pMalloc->Free((void *)pidl);
    }

    return fRet;
}

BOOL IsEmptyDir(const TCHAR *pszDir)
{
    TCHAR szFnd[MAX_PATH];

    _stprintf_s(szFnd, _T("%s//*"), pszDir);
    WIN32_FIND_DATA fd;
    HANDLE hFnd=FindFirstFile(szFnd, &fd);
    if(INVALID_HANDLE_VALUE!=hFnd)
    {
    	return FALSE;
    }

    while( ('.'==fd.cFileName[0])
        && ( (0==fd.cFileName[1])
        || ( ('.'==fd.cFileName[1]) && (0==fd.cFileName[2]) ) ) )
    {
        if(FALSE==FindNextFile(hFnd, &fd))
        {
            FindClose(hFnd);
            return TRUE;
        }
    }
    FindClose(hFnd);
    return FALSE;
}

